package List;

public class SinLinkList implements IList {
    // 头指针
    private SinNode head;

    // 尾指针
    private SinNode tail;

    // 元素个数
    private int length;

    public SinLinkList() {
        this.head = new SinNode();
        this.tail = this.head;
        this.head.setNext(this.head);
        this.length = 0;
    }

    public SinLinkList(SinLinkList other) {
        // TODO
    }

    @Override
    public Object get(int i) throws Exception {
        // 判定下标是否合法
        if (i < 0 || i >= this.length) {
            throw new ArrayIndexOutOfBoundsException(i);
        }
        // 移动元素标记,从头结点开始移动,移动i+1
        SinNode temp = this.head;
        for (int moveCnt = 0; moveCnt <= i; moveCnt++) {
            temp = temp.getNext();
        }
        return temp.getData();
    }

    @Override
    public void insert(Object x) throws Exception {
        // 构造新插入的节点
        SinNode newSinNode = new SinNode(x);
        newSinNode.setNext(this.tail.getNext());
        // 在尾节点后插入新节点
        this.tail.setNext(newSinNode);
        this.tail = newSinNode;
        // 链表长度加1
        this.length++;
    }

    @Override
    public void insert(int i, Object x) throws Exception {
        // 空表插入第1个元素
        if (this.length == 0 && i == 0) {
            this.insert(x);
        }
        if (i < 0 || i >= this.length) {
            throw new ArrayIndexOutOfBoundsException(i);
        }
        // 寻找被删除节点的前一个节点,用q标记
        SinNode q = this.head;
        for (int moveCount = 0; moveCount < i; moveCount++) {
            q = q.getNext();
        }
        // 构造新插入的节点
        SinNode newSinNode = new SinNode(x, q.getNext());
        // 在尾节点后插入新节点
        q.setNext(newSinNode);
        // 链表长度加一
        this.length++;
    }

    @Override
    public Object remove(int i) throws Exception {
        if (i < 0 || i >= this.length) {
            throw new ArrayIndexOutOfBoundsException(i);
        }
        // 寻找被删除节点的前一个节点,用q标记
        SinNode q = this.head;
        for (int moveCount = 0; moveCount < i; moveCount++) {
            q = q.getNext();
        }
        // 被删除节点p
        SinNode p = q.getNext();
        // 删除
        q.setNext(p.getNext());
        p.setNext(null);
        // 链表元素个数减一
        this.length--;
        return p.getData();
    }

    @Override
    public int indexOf(Object x) {
        // 默认找不到元素X,默认返回值为-1
        int result = -1;
        // 查找元素: 遍历链表每一个节点进行比较（查找）
        SinNode temp = this.head.getNext();
        int index = 0;
        while (temp != null && temp != head) {
            if (temp.getData().equals(x)) {
                result = index;
                break;
            }
            index++;
            temp = temp.getNext();
        }
        return result;
    }

    @Override
    public void display() {
        SinNode temp = this.head.getNext();
        System.out.print("[");
        while (temp != head) {
            if (temp == this.head.getNext()) {
                System.out.print(temp.getData());
            } else {
                System.out.print(",");
                System.out.print(temp.getData());
            }
            temp = temp.getNext();
        }
        System.out.println("]");
    }
}
